package com.ning.cloud.gateway.component;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.ning.cloud.gateway.config.JwtProperties;
import com.ning.cloud.gateway.dto.AuthUserDTO;
import com.ning.cloud.gateway.util.JwtTokenUtil;
import jakarta.annotation.Resource;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.ServerHttpRequest;
import reactor.core.publisher.Mono;

@Configuration
public class RateLimitConfig {

    @Resource
    JwtProperties jwtProperties;

    @Resource
    JwtTokenUtil jwtTokenUtil;

    @Bean
    public KeyResolver smartKeyResolver() {
        return exchange -> {
            // 根据请求特征智能选择限流键
            ServerHttpRequest request = exchange.getRequest();

            // 1. 优先按用户限流（如果已认证）
            String userId = getUserId(request);
            if (userId != null) {
                return Mono.just("user:" + userId);
            }

            // 2. 按API路径限流（对于特定API）
            String path = request.getPath().value();
            if (isCriticalApi(path)) {
                return Mono.just("api:" + path);
            }

            // 3. 默认按IP限流
            return Mono.just("ip:" + getClientIp(request));
        };
    }

    private String getUserId(ServerHttpRequest request) {
        try {
            String bearerToken = request.getHeaders().getFirst(jwtProperties.getHeader());
            String jwtToken = null;
            if (org.springframework.util.StringUtils.hasText(bearerToken) && bearerToken.startsWith(jwtProperties.getTokenPrefix())) {
                jwtToken = bearerToken.substring(jwtProperties.getTokenPrefix().length());
            }
            //解析jwt token获取用户信息
            AuthUserDTO authUserDTO = jwtTokenUtil.parseToken(jwtToken);
            if (authUserDTO != null) {
                return authUserDTO.getUserId().toString();
            }
        } catch (Exception e) {
            //异常处理
        }
        return null;
    }

    private boolean isCriticalApi(String path) {
        // 定义需要按API限流的关键接口
        return path.startsWith("/api/user") ||
                path.startsWith("/api/order");
    }

    private String getClientIp(ServerHttpRequest request) {
        // 获取客户端真实IP的实现
        String ip = request.getHeaders().getFirst("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddress().getAddress().getHostAddress();
        }
        return ip;
    }
}